package com.ybkj.daijia;

import java.math.BigInteger;
import java.util.Random;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

/**
 * @author Shine
 */
public class CSRFTokenManager {

    /**
     * CSRF Token 参数的名称
     */
    public static final String Token_NAME = "Token";
    /**
     * CSRF Token 参数的名称
     */
    public static final String CSRF_PARAM_NAME = "CSRFToken";
    /**
     * 存放 CSRF Token 的 Session ID
     */
    public static final String CSRF_TOKEN_FOR_SESSION_ATTR_NAME = "CSRFToken_Session_Id";
    /**
     * 生成一个随机数构造器
     */
    private static final Random RANDOM = new Random(500L);

    /**
     * 工具类不需要实例化
     */
    private CSRFTokenManager() {
    }

    /**
     * 从session中获取token如果没有就生成一个
     *
     * @param session
     * @return
     */
    public static String getTokenForSession(HttpSession session) {

        String token = null;
        synchronized (session) {
            token = (String) session.getAttribute(CSRF_TOKEN_FOR_SESSION_ATTR_NAME);
            if (null == token) {
                token = new BigInteger(165, RANDOM).toString().toUpperCase();
                session.setAttribute(CSRF_TOKEN_FOR_SESSION_ATTR_NAME, token);
            }
        }

        return token;

    }

    /**
     * 从 HTTP 请求中获取 token 值
     *
     * @param req
     * @return
     */
    public static String getTokenFromRequest(HttpServletRequest req) {

        return req.getParameter(CSRF_PARAM_NAME);
    }

    /**
     * 进行CSRF验证
     *
     * @param req
     * @return
     */
    public static boolean isValid(HttpServletRequest req) {

        String token = getTokenFromRequest(req);
        if (null == token || null == req.getSession().getAttribute(CSRF_TOKEN_FOR_SESSION_ATTR_NAME)
            || !token.equals(req.getSession().getAttribute(CSRF_TOKEN_FOR_SESSION_ATTR_NAME))) {

            return false;
        }

        req.getSession().removeAttribute(CSRF_TOKEN_FOR_SESSION_ATTR_NAME); //验证通过删除之前的TOKEN

        return true;
    }

}
